// SPDX-FileCopyrightText: 2024 citrus Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <aidl/com/fanwj/citrus/aidl/BnBackend.h>
#include <aidl/com/fanwj/citrus/aidl/BpFrontend.h>

class Binder : public aidl::com::fanwj::citrus::aidl::BnBackend
{
public:
    static aidl::com::fanwj::citrus::aidl::IFrontend* getInstanceFrontend() {
        return &instance->frontend;
    }
private:
    static std::shared_ptr<Binder> instance;

public:
    Binder(AIBinder_Class* clazz);
    virtual ~Binder() = default;

private:
    aidl::com::fanwj::citrus::aidl::BpFrontend frontend;

protected:
    ::ndk::ScopedAStatus NativeLibrary_setAppDirectory(const std::string& directory) override;
    ::ndk::ScopedAStatus NativeLibrary_installFileToNand(const std::string& filename, int32_t* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_doesUpdateMatchProgram(int64_t programId, const std::string& updatePath, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_initializeGpuDriver(const std::string& hookLibDir, const std::string& customDriverDir, const std::string& customDriverName, const std::string& fileRedirectDir) override;
    ::ndk::ScopedAStatus NativeLibrary_reloadKeys(bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_initializeSystem(bool reload) override;
    ::ndk::ScopedAStatus NativeLibrary_run(const std::string& path, int32_t programIndex, bool frontendInitiated, int64_t* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_surfaceChanged(int32_t width, int32_t height) override;
    ::ndk::ScopedAStatus NativeLibrary_surfaceDestroyed() override;
    ::ndk::ScopedAStatus NativeLibrary_unpauseEmulation() override;
    ::ndk::ScopedAStatus NativeLibrary_pauseEmulation() override;
    ::ndk::ScopedAStatus NativeLibrary_stopEmulation() override;
    ::ndk::ScopedAStatus NativeLibrary_isRunning(bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_isPaused(bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_getPerfStats(std::vector<double>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_getCpuBackend(std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_getGpuDriver(std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_applySettings() override;
    ::ndk::ScopedAStatus NativeLibrary_logSettings() override;
    ::ndk::ScopedAStatus NativeLibrary_logDeviceInfo() override;
    ::ndk::ScopedAStatus NativeLibrary_submitInlineKeyboardText(const std::string& text) override;
    ::ndk::ScopedAStatus NativeLibrary_submitInlineKeyboardInput(int32_t key_code) override;
    ::ndk::ScopedAStatus NativeLibrary_initializeEmptyUserDirectory() override;
    ::ndk::ScopedAStatus NativeLibrary_getAppletLaunchPath(int64_t id, std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_setCurrentAppletId(int32_t appletId) override;
    ::ndk::ScopedAStatus NativeLibrary_setCabinetMode(int32_t cabinetMode) override;
    ::ndk::ScopedAStatus NativeLibrary_isFirmwareAvailable(bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_getPatchesForFile(const std::string& path, int64_t programId, std::vector<::aidl::com::fanwj::citrus::aidl::IBackend::Patch>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_removeUpdate(int64_t programId) override;
    ::ndk::ScopedAStatus NativeLibrary_removeDLC(int64_t programId) override;
    ::ndk::ScopedAStatus NativeLibrary_removeMod(int64_t programId, const std::string& name) override;
    ::ndk::ScopedAStatus NativeLibrary_verifyInstalledContents(std::vector<std::string>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_verifyGameContents(const std::string& path, int32_t* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_getSavePath(int64_t programId, std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_getDefaultProfileSaveDataRoot(bool future, std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_addFileToFilesystemProvider(const std::string& path) override;
    ::ndk::ScopedAStatus NativeLibrary_clearFilesystemProvider() override;
    ::ndk::ScopedAStatus NativeLibrary_areKeysPresent(bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeLibrary_syncFileDescriptor(int64_t addr) override;
    ::ndk::ScopedAStatus NativeInput_isHandheldOnly(bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_onGamePadButtonEvent(const std::string& guid, int32_t port, int32_t buttonId, int32_t action) override;
    ::ndk::ScopedAStatus NativeInput_onGamePadAxisEvent(const std::string& guid, int32_t port, int32_t axis, float value) override;
    ::ndk::ScopedAStatus NativeInput_onGamePadMotionEvent(const std::string& guid, int32_t port, int64_t deltaTimestamp, float xGyro, float yGyro, float zGyro, float xAccel, float yAccel, float zAccel) override;
    ::ndk::ScopedAStatus NativeInput_onReadNfcTag(const std::vector<uint8_t>& data) override;
    ::ndk::ScopedAStatus NativeInput_onRemoveNfcTag() override;
    ::ndk::ScopedAStatus NativeInput_onTouchPressed(int32_t fingerId, float xAxis, float yAxis) override;
    ::ndk::ScopedAStatus NativeInput_onTouchMoved(int32_t fingerId, float xAxis, float yAxis) override;
    ::ndk::ScopedAStatus NativeInput_onTouchReleased(int32_t fingerId) override;
    ::ndk::ScopedAStatus NativeInput_onOverlayButtonEventImpl(int32_t port, int32_t buttonId, int32_t action) override;
    ::ndk::ScopedAStatus NativeInput_onOverlayJoystickEventImpl(int32_t port, int32_t stickId, float xAxis, float yAxis) override;
    ::ndk::ScopedAStatus NativeInput_onDeviceMotionEvent(int32_t port, int64_t deltaTimestamp, float xGyro, float yGyro, float zGyro, float xAccel, float yAccel, float zAccel) override;
    ::ndk::ScopedAStatus NativeInput_reloadInputDevices() override;
    ::ndk::ScopedAStatus NativeInput_getInputDevices(std::vector<std::string>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_loadInputProfiles() override;
    ::ndk::ScopedAStatus NativeInput_getInputProfileNames(std::vector<std::string>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_isProfileNameValid(const std::string& name, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_createProfile(const std::string& name, int32_t playerIndex, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_deleteProfile(const std::string& name, int32_t playerIndex, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_loadProfile(const std::string& name, int32_t playerIndex, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_saveProfile(const std::string& name, int32_t playerIndex, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_loadPerGameConfiguration(int32_t playerIndex, int32_t selectedIndex, const std::string& selectedProfileName) override;
    ::ndk::ScopedAStatus NativeInput_beginMapping(int32_t type) override;
    ::ndk::ScopedAStatus NativeInput_getNextInput(std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_stopMapping() override;
    ::ndk::ScopedAStatus NativeInput_updateMappingsWithDefaultImpl(int32_t playerIndex, const std::string& deviceParams, const std::string& displayName) override;
    ::ndk::ScopedAStatus NativeInput_getButtonParamImpl(int32_t playerIndex, int32_t buttonId, std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_setButtonParamImpl(int32_t playerIndex, int32_t buttonId, const std::string& param) override;
    ::ndk::ScopedAStatus NativeInput_getStickParamImpl(int32_t playerIndex, int32_t stickId, std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_setStickParamImpl(int32_t playerIndex, int32_t stickId, const std::string& param) override;
    ::ndk::ScopedAStatus NativeInput_getButtonNameImpl(const std::string& param, int32_t* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_getSupportedStyleTagsImpl(int32_t playerIndex, std::vector<int32_t>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_getStyleIndexImpl(int32_t playerIndex, int32_t* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_setStyleIndexImpl(int32_t playerIndex, int32_t styleIndex) override;
    ::ndk::ScopedAStatus NativeInput_isControllerImpl(const std::string& params, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_getIsConnected(int32_t playerIndex, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeInput_connectControllersImpl(const std::vector<bool>& connected) override;
    ::ndk::ScopedAStatus NativeInput_resetControllerMappings(int32_t playerIndex) override;
    ::ndk::ScopedAStatus NativeConfig_initializeGlobalConfig() override;
    ::ndk::ScopedAStatus NativeConfig_unloadGlobalConfig() override;
    ::ndk::ScopedAStatus NativeConfig_reloadGlobalConfig() override;
    ::ndk::ScopedAStatus NativeConfig_saveGlobalConfig() override;
    ::ndk::ScopedAStatus NativeConfig_initializePerGameConfig(int64_t programId, const std::string& fileName) override;
    ::ndk::ScopedAStatus NativeConfig_isPerGameConfigLoaded(bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_savePerGameConfig() override;
    ::ndk::ScopedAStatus NativeConfig_unloadPerGameConfig() override;
    ::ndk::ScopedAStatus NativeConfig_getBoolean(const std::string& key, bool needsGlobal, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setBoolean(const std::string& key, bool value) override;
    ::ndk::ScopedAStatus NativeConfig_getByte(const std::string& key, bool needsGlobal, int8_t* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setByte(const std::string& key, int8_t value) override;
    ::ndk::ScopedAStatus NativeConfig_getShort(const std::string& key, bool needsGlobal, char16_t* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setShort(const std::string& key, char16_t value) override;
    ::ndk::ScopedAStatus NativeConfig_getInt(const std::string& key, bool needsGlobal, int32_t* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setInt(const std::string& key, int32_t value) override;
    ::ndk::ScopedAStatus NativeConfig_getFloat(const std::string& key, bool needsGlobal, float* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setFloat(const std::string& key, float value) override;
    ::ndk::ScopedAStatus NativeConfig_getLong(const std::string& key, bool needsGlobal, int64_t* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setLong(const std::string& key, int64_t value) override;
    ::ndk::ScopedAStatus NativeConfig_getString(const std::string& key, bool needsGlobal, std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setString(const std::string& key, const std::string& value) override;
    ::ndk::ScopedAStatus NativeConfig_getIsRuntimeModifiable(const std::string& key, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_getPairedSettingKey(const std::string& key, std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_getIsSwitchable(const std::string& key, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_usingGlobal(const std::string& key, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setGlobal(const std::string& key, bool global) override;
    ::ndk::ScopedAStatus NativeConfig_getIsSaveable(const std::string& key, bool* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_getDefaultToString(const std::string& key, std::string* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_getGameDirs(std::vector<::aidl::com::fanwj::citrus::aidl::IBackend::GameDir>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setGameDirs(const std::vector<::aidl::com::fanwj::citrus::aidl::IBackend::GameDir>& dirs) override;
    ::ndk::ScopedAStatus NativeConfig_addGameDir(const ::aidl::com::fanwj::citrus::aidl::IBackend::GameDir& dir) override;
    ::ndk::ScopedAStatus NativeConfig_getDisabledAddons(int64_t programId, std::vector<std::string>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setDisabledAddons(int64_t programId, const std::vector<std::string>& disabledAddons) override;
    ::ndk::ScopedAStatus NativeConfig_getOverlayControlData(std::vector<::aidl::com::fanwj::citrus::aidl::IBackend::OverlayControlData>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setOverlayControlData(const std::vector<::aidl::com::fanwj::citrus::aidl::IBackend::OverlayControlData>& overlayControlData) override;
    ::ndk::ScopedAStatus NativeConfig_getInputSettings(bool global, std::array<::aidl::com::fanwj::citrus::aidl::IBackend::PlayerInput, 10>* _aidl_return) override;
    ::ndk::ScopedAStatus NativeConfig_setInputSettings(const std::array<::aidl::com::fanwj::citrus::aidl::IBackend::PlayerInput, 10>& value, bool global) override;
    ::ndk::ScopedAStatus NativeConfig_saveControlPlayerValues() override;
    ::ndk::ScopedAStatus Log_debug(const std::string& message) override;
    ::ndk::ScopedAStatus Log_warning(const std::string& message) override;
    ::ndk::ScopedAStatus Log_info(const std::string& message) override;
    ::ndk::ScopedAStatus Log_error(const std::string& message) override;
    ::ndk::ScopedAStatus Log_critical(const std::string& message) override;
    ::ndk::ScopedAStatus GameMetadata_getMetadata(const std::string& path, bool reload, ::aidl::com::fanwj::citrus::aidl::IBackend::RomMetadata* _aidl_return) override;
    ::ndk::ScopedAStatus GameMetadata_isValid(const std::string& path, bool* _aidl_return) override;
    ::ndk::ScopedAStatus GameMetadata_resetMetadata() override;
    ::ndk::ScopedAStatus GpuDriverHelper_supportsCustomDriverLoading(bool* _aidl_return) override;
    ::ndk::ScopedAStatus GpuDriverHelper_getSystemDriverInfo(const std::string& hookLibPath, std::vector<std::string>* _aidl_return) override;
    ::ndk::SpAIBinder createBinder() override;

private:
    friend int main(int argc, char *argv[]);
};